#include "cas_keep.h"
#include "scheduler.h"
#include "slave.h"
#include "task.h"
#include "MemPool.h"
int ref_count(struct task *self) { return self->ref_count_t; }

/*int is_stolen_task(struct task* self)
{
    return (self->extra_state) & 0x80;
}*/
void slave_task_constructor(struct task *self)
{
    // struct task self ;
printf("slave_task_cons\n");    
self->ref_count_t = -1;
#ifdef REUSE_GRAPH
    self->backup_ref = -1;
    self->reused = 0;
    self->stored = 0;
    self->is_base_task = 1;
#endif
    self->affinity_id = INIT_AFFINITY;
#if defined(USE_PRIORITY_QUEUE) || defined(LOCAL_MULTI_PRIORI)
    self->priority_id = 0;
#endif
    // self->spawn_order_id = 0;
    self->next = NULL;
    // self->extra_state = 0;
    // return self;
}
#ifdef CONCURRENT_CONSTRUCT_GRAPH
/*
inline void set_pre(struct task* self,int p)
{
    self->pre = p;
}
inline int pre_count(struct task* self)
{
    return self->pre;
}
*/
#endif

void spawn(struct task *t) { slave_spawn_to_id(t); }

void setparent(struct task *child_task, struct task *t)
{
    child_task->parent = t;
    if (t != NULL)
{
int val = 0;
        updt_subw(val, &(t->_countdownToBeWokenUp));
}
// (t->_countdownToBeWokenUp)--;
}
struct task *getparent(struct task *t) { return t->parent; }
void initprecount(struct task *t)
{
    t->_predecessorCount = -1;
    t->_countdownToBeWokenUp = -1;
    t->_endExecute = 0;
}
void initTaskDataAccess(struct task *t, int _size)
{
printf("begin init\n");    
t->_dataAccesses._accessArray =slave_acemesh_myalloc_aligned_16(sizeof(void *)*_size,_MYID); //libc_uncached_aligned_malloc(sizeof(struct DataAccess) * _size);
    t->_dataAccesses._addressArray =slave_acemesh_myalloc_aligned_16(sizeof(void*)*_size,_MYID); //libc_uncached_aligned_malloc(sizeof(void *) * _size);
printf("after malloc\n");
    t->_dataAccesses._currentIndex = 0;
    // _dataAccesses._accessMap = nullptr;
    t->_dataAccesses._subaccessBottomMap = slave_createHashMap();
printf("hashmap:%p\n", t->_dataAccesses._subaccessBottomMap);    
for(int i=0;i<t->_dataAccesses._subaccessBottomMap->listSize; i++){
    printf("entry:%p,key:%p,value:%p\n",t->_dataAccesses._subaccessBottomMap->list[i],t->_dataAccesses._subaccessBottomMap->list[i].key,t->_dataAccesses._subaccessBottomMap->list[i].value);
}
}
struct TaskDataAccesses *getDataAccesses(struct task *t) { return &(t->_dataAccesses); }
struct DataAccess *findAccess(struct task *t, void *address)
{
    // if (_accessMap != nullptr) {
    // 	access_map_t::iterator itAccess = _accessMap->find(address);
    // 	if (itAccess != _accessMap->end())
    // 		return &itAccess->second;
    // } else {
    int size = t->_dataAccesses._currentIndex;
    for (size_t i = 0; i < size; ++i) {
        if (t->_dataAccesses._addressArray[i] == address)
            return &(t->_dataAccesses._accessArray[i]);
    }
    //}

    return NULL;
}
void setChild(struct DataAccess *parent, struct DataAccess *child)
{
    // (parent->_child).store(child, std::memory_order_seq_cst);
 
   parent->_child = child;
 int val = 0;
    updt_subw(val, &((child->_originator)->_predecessorCount));
 //   ((child->_originator)->_predecessorCount)--;
}
void setSuccessor(struct DataAccess *pre, struct DataAccess *successor)
{
    // (pre->_successor).store(successor, std::memory_order_seq_cst);
    pre->_successor = successor;
 int val = 0;
    updt_subw(val, &((successor->_originator)->_predecessorCount));  
//  ((successor->_originator)->_predecessorCount)--;
}
int predec_count(struct task *t) { return t->_predecessorCount; }
int dec_predecessorCount(struct task *t)
{
    int res = (t->_predecessorCount -= 1);
    // assert(res >= 0);
    return (res == 0);
}
int child_count(struct task *t) { return t->_countdownToBeWokenUp; }
int dec_childCount(struct task *t)
{
    int res = (t->_countdownToBeWokenUp -= 1);
    // assert(res >= 0);
    return (res == 0);
}
int inc_predecessorCount(struct task *t) { t->_predecessorCount += 1; }
